﻿#region Imports
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Forms;
using IntelliSearch.Controls;
using IntelliSearch.Models;
using IntelliSearch.Utilities;
#endregion

namespace IntelliSearch
{
    public partial class frmIntelliSearch : Form
    {
        #region Declarations
        ObservableCollection<Contacts> filteredContacts;
        ObservableCollection<Contacts> selectedContacts;
        #endregion

        #region Properties
        public ObservableCollection<Contacts> AllContacts { get; set; }
        public Dictionary<string, List<char>> AlphaNumValues { get; set; }

        private Contacts loadedContact;
        public Contacts LoadedContact
        {
            get { return loadedContact; }
            set
            {
                loadedContact = value;

                EvaluateButtons();
                lblSelectedContact.Text = loadedContact.FullName;
                // Fill fields
            }
        }
        #endregion

        #region Constructors
        public frmIntelliSearch()
        {
            InitializeComponent();

            AlphaNumValues = AlphaNumerics.AlphaNumValues;

            AllContacts = new ObservableCollection<Contacts>();
            AllContacts.Add(new Contacts { FName = "A B", MName = "C", LName = "D E F", NickName = "TEST", PhoneNum = "1234" });
            AllContacts.Add(new Contacts { FName = "R", MName = "K", LName = "D", NickName = "Me", PhoneNum = "12345" });
            AllContacts.Add(new Contacts { FName = "Rupak", MName = "Kr", LName = "Das", NickName = "Me", PhoneNum = "23456" });
            AllContacts.Add(new Contacts { FName = "Rishabh", LName = "Barua", NickName = "rsv", PhoneNum = "1234" });
            AllContacts.Add(new Contacts { FName = "Hirok", MName = "Kumar", LName = "Das", NickName = "baba", PhoneNum = "1234" });
            AllContacts.Add(new Contacts { FName = "Kaustav", LName = "Dutta", NickName = "kd", PhoneNum = "1234" });
            AllContacts.Add(new Contacts { FName = "Srimoyi", LName = "Mazumder", NickName = "sm", PhoneNum = "1234" });
            AllContacts.Add(new Contacts { FName = "Avishek", LName = "Patra", NickName = "patra", PhoneNum = "1234" });

            lstContacts.DataSource = new ObservableCollection<object>(AllContacts);
            lstContacts.DisplayMember = "FullName";
            lstContacts.ValueMember = "Id";
        }
        #endregion

        #region Events
        private void frmIntelliSearch_Load(object sender, EventArgs e)
        {
            int top = 0; int left = 0; int width = 0; int itemsPerLine = 3;
            foreach (var dict in AlphaNumValues)
            {
                string key = dict.Key;
                string val = dict.Value.ToCharString();
                string name = "btn" + val;
                width = pnlButtons.Width / itemsPerLine - 5;

                AlphaNumButton btn = new AlphaNumButton { Name = name, ValueNum = Convert.ToInt32(key), ValueAlpha = val, Text = key + "\n" + val.Replace(" ", "(Space)"), Top = top, Left = left, Height = 40, Width = width };
                btn.Click += new EventHandler(btn_Click);
                pnlButtons.Controls.Add(btn);

                if (pnlButtons.Controls.Count % itemsPerLine == 0) top += pnlButtons.Controls[name].Height + 5;
                if (pnlButtons.Controls.Count % itemsPerLine == 0) left = pnlButtons.Controls[0].Left;
                else left += pnlButtons.Controls[name].Width + (pnlButtons.Width - width * itemsPerLine) / (itemsPerLine - 1);

                //Distribution_of_controlsfor < 3;
            }


            /*
            int xCount = 0;
            foreach (RepeaterItem item in RPProjectType.Items)
            {
                The three findcontrol are causing an trouble - see error message below:

                Label lblCategory = (Label)item.FindControl("lblCategory");
                Label lblCategory = (Label)RPProjectType.Controls[0].Controls[0].FindControl("lblCategory");  <--- application fails here 
	            Label lblSubCategory = (Label)item.FindControl("lblSubCategory");
                Label lblSubCategory = (Label)RPProjectType.Controls[1].Controls[1].FindControl("lblSubCategory");
	            Label lblQuestion = (Label)item.FindControl("lblQuestion");
                Label lblQuestion = (Label)RPProjectType.Controls[2].Controls[2].FindControl("lblQuestion");

                if (Convert.ToInt32(cbxLTProjectType.SelectedValue) == 100)
                {
                    //my codes
                }
            }
            */
        }

        private void btn_Click(object sender, EventArgs e)
        {
            txtValue.Text += ((AlphaNumButton)sender).ValueNum;
            txtValue.Focus();
        }

        private void txtValue_TextChanged(object sender, EventArgs e)
        {
            string value = txtValue.Text;

            // Number search
            filteredContacts = new ObservableCollection<Contacts>(AllContacts.Where(cxt => cxt.PhoneNum.Contains(value)));

            // Intelli search
            int pos = 0;
            ObservableCollection<Contacts> tempNameSearch = new ObservableCollection<Contacts>(AllContacts);
            ObservableCollection<Contacts> tempInitialsSearch = new ObservableCollection<Contacts>(AllContacts);
            foreach (char num in value.ToCharArray())
            {
                pos++;

                #region MyRegion
                //AlphaNumValues[pos.ToString()];
                #endregion

                // Search in FName, MName, LName
                //tempNameSearch = tempNameSearch.Where(cxt => AlphaNumerics.CheckAlphaNumAssoc(cxt.FName, pos, num)
                //    //cxt => (cxt.FName.Length >= pos ? AlphaNumValues[num.ToString()].Contains(cxt.FName.ElementAt(pos - 1)) : true)
                //    //|| (cxt.MName.Length >= pos ? AlphaNumValues[num.ToString()].Contains(cxt.MName.ElementAt(pos - 1)) : true)
                //    //|| (cxt.LName.Length >= pos ? AlphaNumValues[num.ToString()].Contains(cxt.LName.ElementAt(pos - 1)) : true)
                //    //|| (cxt.NickName.Length >= pos ? AlphaNumValues[num.ToString()].Contains(cxt.NickName.ElementAt(pos - 1)) : true)
                //            || AlphaNumerics.CheckAlphaNumAssoc(cxt.MName, pos, num)
                //            || AlphaNumerics.CheckAlphaNumAssoc(cxt.LName, pos, num)
                //            || AlphaNumerics.CheckAlphaNumAssoc(cxt.NickName, pos, num)
                //                    ).ToObservableCollection();
                tempNameSearch = tempNameSearch.Where(cxt => CheckAlphaNumAssoc(cxt, pos, num)).ToObservableCollection();

                // Search in Initials
                if (pos <= 3)
                    tempInitialsSearch = tempInitialsSearch.Where(cxt =>
                        //AlphaNumValues[num.ToString()].Contains(cxt.Initials.ElementAt(pos - 1))
                        AlphaNumerics.CheckAlphaNumAssoc(cxt.Initials, pos, num)).ToObservableCollection();
            }

            tempNameSearch.ToList().ForEach(cxt => filteredContacts.Add(cxt));
            lstContacts.DataSource = new ObservableCollection<object>(
                (filteredContacts.Unions(tempNameSearch, tempInitialsSearch)).Distinct().OrderBy(cxt => cxt.FullName));
            lstContacts.DisplayMember = "FullName";
            lstContacts.ValueMember = "Id";

            SendKeys.Send("{End}");
        }

        private bool CheckAlphaNumAssoc(Contacts cxt, int pos, char num)
        {
            return AlphaNumerics.CheckAlphaNumAssoc(cxt.FName, pos, num)
                || AlphaNumerics.CheckAlphaNumAssoc(cxt.MName, pos, num)
                || AlphaNumerics.CheckAlphaNumAssoc(cxt.LName, pos, num)
                || AlphaNumerics.CheckAlphaNumAssoc(cxt.FullName, pos, num)
                || AlphaNumerics.CheckAlphaNumAssoc(cxt.NickName, pos, num);
        }
        #endregion

        private void cmnuEditSelectedContacts_Click(object sender, EventArgs e)
        {
            selectedContacts = lstContacts.SelectedItems.Cast<Contacts>().OrderBy(cxt => cxt.FullName).ToObservableCollection();

            if (selectedContacts.Any())
                LoadedContact = selectedContacts.First();
            else
                lblSelectedContact.Text = "None selected";
        }

        private void txtValue_KeyDown(object sender, KeyEventArgs e)
        {
            // Allow Del/BackSpace/Numerals
        }

        private void btnMoveContact_Click(object sender, EventArgs e)
        {
            switch (((Button)sender).Name.TrimStart("btn"))
            {
                case "First":
                    LoadedContact = selectedContacts.First();
                    break;
                case "Last":
                    LoadedContact = selectedContacts.Last();
                    break;
                case "Prev":
                    LoadedContact = selectedContacts.ElementAt(selectedContacts.IndexOf(loadedContact) - 1);
                    break;
                case "Next":
                    LoadedContact = selectedContacts.ElementAt(selectedContacts.IndexOf(loadedContact) + 1);
                    break;
                default:
                    break;
            }
        }

        private void EvaluateButtons()
        {
            btnFirst.Enabled = (selectedContacts.Count() > 2 && loadedContact != selectedContacts.First());
            btnLast.Enabled = (selectedContacts.Count() > 2 && loadedContact != selectedContacts.Last());
            btnPrev.Enabled = (loadedContact != selectedContacts.First());
            btnNext.Enabled = (loadedContact != selectedContacts.Last());
        }
    }
}

// DataRepeater Control for Windows Forms :: http://blogs.msdn.com/b/vsdata/archive/2009/08/12/datarepeater-control-for-windows-forms.aspx
// Binding SQL Data to a Repeater Control :: http://msdn.microsoft.com/en-us/library/aa719636(v=vs.71).aspx
//
